/*
 * File Name  :ActionServlet.java
 * Create Date:2012-11-6 上午12:10:36
 * Author     :woden
 */

package com.wodensoft.core.web;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wodensoft.core.BeanFactory;

/**
 * 基础Action处理框架.
 * 
 */
@SuppressWarnings("serial")
public final class ActionServlet extends HttpServlet {
    private static final Logger logger = LoggerFactory.getLogger(ActionServlet.class);

    private static final String CLASS_ROOT = "com.wodensoft.module";// action路径

    public ActionServlet() {
        super();
    }

    public void init() throws ServletException {
        super.init();
    }

    public void destroy() {
        super.destroy();
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        service(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        service(request, response);
    }

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        initAttributes(request);
        
        String classname = null;
        String method = null;
        String strPathInfo = request.getServletPath();
        if (strPathInfo != null) {
            strPathInfo = strPathInfo.substring(1, strPathInfo.lastIndexOf("."));
            classname = CLASS_ROOT + "." + strPathInfo.substring(0, strPathInfo.lastIndexOf("/")).replaceAll("/", ".");
            method = strPathInfo.substring(strPathInfo.lastIndexOf("/") + 1, strPathInfo.length());
        }

        if (classname == null || method == null) {
            String strErrMsg = "类|方法 不存在.";
            logger.error(strErrMsg);
            throw new ServletException(strErrMsg);
        }

        try {
            Class<?> clazz = Class.forName(classname);
            // 从spring工厂生成实例,action是无状态的，所以一个实例即可
            Object obj = BeanFactory.getInstance().getSingleBean(clazz);
            Method mth = clazz.getMethod(method, new Class[] { HttpServletRequest.class, HttpServletResponse.class });
            mth.invoke(obj, new Object[] { request, response });
        } catch (ClassNotFoundException e) {
            logger.error("类[" + classname + "]不存在.", e);
            try {
                Actions.redirectErrorPage(request, response, "地址不存在.");
            } catch (Exception ex) {
                throw new ServletException(e);
            }
        } catch (NoSuchMethodException e) {
            logger.error("方法[" + method + "]不存在.", e);
            try {
                Actions.redirectErrorPage(request, response, "地址不存在.");
            } catch (Exception ex) {
                throw new ServletException(e);
            }
        } catch (Throwable e) {
            String strErrMsg = ExceptionUtils.getRootCauseMessage(e) + "." + "请联系管理员.";
            logger.error(strErrMsg, e);
            try {
                Actions.redirectErrorPage(request, response, strErrMsg);
            } catch (Exception ex) {
                throw new ServletException(e);
            }
        }
    }

    private void initAttributes(HttpServletRequest request) {
        // 获取zoneid
        String zoneId = request.getParameter(Actions.Keys.ZONE.toString());
        request.setAttribute(Actions.Keys.ZONE.toString(), zoneId);

        // 设置根路径
        request.setAttribute(Actions.Keys.CP.toString(), Actions.Util.getContextPath(request));

        // 设置当前action url
        request.setAttribute(Actions.Keys.ACTION.toString(), Actions.Util.getActionUrl(request));
        request.setAttribute(Actions.Keys.CUR_URL.toString(), request.getServletPath());

        // 分页和排序
        request.setAttribute(Actions.Keys.LIMIT.toString(), Actions.Util.getLimit(request));
        request.setAttribute(Actions.Keys.PAGE.toString(), request.getParameter(Actions.Keys.PAGE.toString()));
        request.setAttribute(Actions.Keys.FIELD.toString(), request.getParameter(Actions.Keys.FIELD.toString()));
        request.setAttribute(Actions.Keys.DIR.toString(), request.getParameter(Actions.Keys.DIR.toString()));
    }
}
